// -----------------------------------------------------------------------
//  <copyright file="CreateRoleCommand.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2024 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2024/12/10 14:32:37</last-date>
// -----------------------------------------------------------------------

using DaprPlus.Identity.Domain.Entities;
using DaprPlus.Identity.Domain.IntegrationEvents;

using DaprPlus.Identity.Application.Identity.Roles.Queries;

using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;

namespace DaprPlus.Identity.Application.Identity.Roles.Commands;

[AuthConfig(typeof(Role), ResourceAccessType.RoleLimit, "Create")]
public class CreateRoleCommand : IRequest<ApiResult>, ICommand
{
    public required RoleInDto[] Dtos { get; set; }
}

public class CreateRoleCommandHandler(IServiceProvider provider)
    : IRequestHandler<CreateRoleCommand, ApiResult>
{
    public async Task<ApiResult> Handle(CreateRoleCommand request, CancellationToken cancellationToken)
    {
        var roleManager = provider.GetRequiredService<RoleManager<Role>>();
        var repository = provider.GetRepository<Role>();
        var createdRoles = new List<RoleInRecord>();

        foreach (var dto in request.Dtos)
        {
            var entity = dto.MapTo<Role>();
            entity.SetId();
            var result = await roleManager.CreateAsync(entity);
            if (!result.Succeeded)
            {
                return new ApiResult(ApiResultType.Error, result.Errors.First().Description);
            }

            var spec = new RoleByIdSpec<Role>(entity.Id);
            entity = await repository.GetAsync(spec, cancellationToken);
            if (entity != null)
            {
                createdRoles.Add(new RoleInRecord(entity.Id, entity.Name, entity.IsLocked));
            }
        }

        var @event = new RoleCreatedIntegrationEvent([.. createdRoles]);
        var uow = provider.GetUnitOfWork();
        uow.AddIntegrationEvent(@event);

        return new ApiResult(ApiResultType.Success, $"角色“{createdRoles.ExpandAndToString(m => m.Name)}”创建成功");
    }
}

